﻿using System;
using System.Diagnostics;

using BizElements.Core.ProviderComponents;

namespace BizElements.Core
{
    /// <summary>
    /// Execution statistics for SQL commands sent from application to database.
    /// </summary>
    /// <remarks>Use only for debuging and tracing purposses to examine the SQL command that was
    /// actually executed on the data-source. The behavior may change in future releases.</remarks>
    public sealed class CommandExecutionStatistics
    {
        #region Fields.

        DateTime startTime = DateTime.Now;
        DateTime endTime;
        object command;

        #endregion

        #region Constructors.

        /// <summary>
        /// Initializes a new instance of <b>CommandExecutionStatistics</b> class.
        /// </summary>
        public CommandExecutionStatistics()
        {
        }

        /// <summary>
        /// Initializes a new instance of <b>CommandExecutionStatistics</b> class.
        /// </summary>
        /// <param name="command">Reference to the command that was executed on the data-source. 
        /// <b>Nullable</b>. Typically a string or an <b>SqlStatementBase</b> object.</param>
        public CommandExecutionStatistics(object command)
        {
            this.command = command;
        }

        #endregion

        #region Methods.

        /// <summary>
        /// Sets the EndTime property to the DateTime.Now value and triggers tracing ig <see cref="Settings.CommandExecutionStatisticsLogged"/> is set to <b>true</b>.
        /// </summary>
        public void StopTime()
        {
            this.endTime = DateTime.Now;
            if (Settings.CommandExecutionStatisticsLogged && this.command != null)
                TraceExecution();
        }

        private void TraceExecution()
        {
            Trace.Write("Elements: ");
            Trace.WriteLine(this.command);
        }

        #endregion

        #region Properties.

        /// <summary>
        /// Gets or sets the time before the command is executed.
        /// </summary>
        public DateTime StartTime
        {
            get { return this.startTime; }
            set { this.startTime = value; }
        }

        /// <summary>
        /// Gets or sets the time after the command is executed.
        /// </summary>
        public DateTime EndTime
        {
            get { return this.endTime; }
            set { this.endTime = value; }
        }

        /// <summary>
        /// Gets the total duration of command execution.
        /// </summary>
        /// <remarks>Includes the time required to send the command to the data-source, time to execute
        /// the command on the data-source and time to return query results back to the application.</remarks>
        public TimeSpan Duration
        {
            get
            {
                if (this.endTime > this.startTime)
                    return this.endTime - this.startTime;
                else
                    return TimeSpan.Zero;
            }
        }

        /// <summary>
        /// Gets ot sets the reference to the command that was executed on the data-source. 
        /// <b>Nullable</b>. Typically a string or an <b>SqlStatementBase</b> object.
        /// </summary>
        public object Command
        {
            get { return this.command; }
            set { this.command = value; }
        }

        #endregion
    }
}